package com.founder.barcode.bussiness.code;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.xerces.impl.dv.util.Base64;

import com.founder.barcode.bussiness.util.DESUtil;
import com.founder.barcode.bussiness.util.MemCacheUtil;
import com.founder.barcode.bussiness.xml.XmlParserUtil;
import com.founder.barcode.common.util.Base64Util;
import com.founder.barcode.common.util.MD5Util;

/**
 * 测试报文生成工具类
 * @author hucw
 *
 */
public class BuildXml extends BaseTest {
    
    public String genTransactionId(String prefix,String suffix) {
        prefix = StringUtils.trimToEmpty(prefix);
        suffix = StringUtils.trimToEmpty(suffix);
        StringBuffer sb = new StringBuffer();
        sb.append(prefix).append(DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS"));
        sb.append(new Random().nextInt(9999));
        sb.append(suffix);
        return sb.toString();
    }
    
    public String genTransactionId() {
        return this.genTransactionId(null, null);
    }
    
    public String getDeviceKey(String deviceId)  {
        return (String)MemCacheUtil.getInstance().getCache("device_" + deviceId);
    }
    
    
    /**
     * 机具签到报文
     * @param deviceId
     * @return
     * @throws IOException
     */
    public String founderSignInXml(String deviceId) throws IOException {
        String xmlStr = this.getXml("/template/founderSign.xml");
        String transactionId = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS");
        String SoftVersion = XmlParserUtil.getXMLValue(xmlStr, "SoftVersion");
        String signKey = MD5Util.encodeByMD5(transactionId + deviceId + SoftVersion);
        Map<String, String> params = new HashMap<String,String>();
        params.put("TransactionID", transactionId);
        params.put("DeviceID", deviceId);
        params.put("SignKey", signKey);
        return this.replaceXml(xmlStr, params);
    }
    
    
    public String founderValidateXml(String deviceID,String entryKey,
            String contentType,String content,String telNo,
            String applyAmount,String applyPassword) throws IOException {
        String xmlStr = this.getXml("/template/founderValidate.xml");
        String softVersion = XmlParserUtil.getXMLValue(xmlStr, "SoftVersion");
        String transactionID = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS");
        String vetifyCode="";
        StringBuffer sb = new StringBuffer();
        sb.append(entryKey).append(content)
            .append(deviceID).append(softVersion)
            .append(transactionID);
        String validateKey = MD5Util.encodeByMD5(sb.toString());
        Map<String,String> params = new HashMap<String, String>();
        params.put("TransactionID", transactionID);
        params.put("DeviceID", deviceID);
        params.put("ValidateKey", validateKey);
        params.put("ContentType", contentType);
        params.put("Content", content);
        params.put("VetifyCode", vetifyCode);
        params.put("TelNo", telNo);
        params.put("ApplyAmount",applyAmount);
        params.put("ApplyPassword",applyPassword);
        xmlStr = this.replaceXml(xmlStr,params);
        return xmlStr;
    }
    
    /**
     * 机具冲正报文
     * @return
     * @throws IOException 
     */
    public String founderReversalXml(String deviceId,String entryKey,String orgTID) throws IOException {
        String xmlStr = this.getXml("/template/founderReversal.xml");
        String transactionID = this.genTransactionId();
        String softVersion = XmlParserUtil.getXMLValue(xmlStr, "SoftVersion");
        StringBuffer sb = new StringBuffer();
        sb.append(entryKey).append(orgTID).append(deviceId).append(softVersion)
            .append(transactionID);
        String checkSum = MD5Util.encodeByMD5(sb.toString());
        
        Map<String, String> params = new HashMap<String, String>();
        params.put("TransactionID",transactionID );
        params.put("DeviceID",deviceId );
        params.put("ValidateKey", checkSum);
        params.put("OrgTID",orgTID);
        xmlStr = this.replaceXml(xmlStr,params);
        return xmlStr;
    }
    
    
    public String codeMakeAndSendXml(String businessId,String ruleId,String sendType,String phoneNo) throws Exception {
        Map<String, String> params = new HashMap<String, String>();
        String transactionID = this.genTransactionId(businessId,null);
        params.put("TransactionID", transactionID);
        //"82288"
        params.put("BusinessID", businessId);
        //"10008"
        params.put("WarrantID", ruleId);
        int batchID = RandomUtils.nextInt(9999);
        params.put("BatchID", String.valueOf(batchID));
        params.put("Number", phoneNo);
        //1：短信；2：彩信； 3：短彩同时发。
        params.put("SendType", sendType);
        //Type=0，将文字BASE64编码后传输,Type=1，ZIP格式彩信包,Type=2，
        params.put("Type", "0");
        params.put("Subject", "中国移动电子礼品券");
        params.put("Mtext", "验证码:@@，尊敬的中国移动用户，您已成功办理了沈阳移动公司“2014年存话费赠礼品”活动。您可凭此二维码彩信到以下任意商家兑换价值50元礼品一份。指定商家为：华润万家超市（沈新店、文化店、铁西店、凯翔店、联合路店、工人村店、沈辽店）、兴隆大家庭（中街店、铁西店）、沈阳新玛特（中街店、铁西店）、中兴商业大厦等。本彩信自收到当日起30天内有效，只可验证兑换取礼品一次。温馨提示：1、本彩信是您领取礼品的凭证，请勿删除；2、请在有效期内使用；3、为了保证您的正常接收，我们将同时下发一条短信，该短信与本彩信作用相同，二者只可用其一。");
        params.put("SText", "验证码:@@，凭此短信可在指定商家兑换价值50元好礼一份，有效期30天。");
        params.put("Content", "");
        
        //base64，防止中文乱码
        params.put("Subject", Base64Util.getBase64EncodeStr(params.get("Subject")));
        params.put("Mtext", Base64Util.getBase64EncodeStr(params.get("Mtext")));
        params.put("SText", Base64Util.getBase64EncodeStr(params.get("SText")));
        params.put("Content", Base64Util.getBase64EncodeStr(params.get("Content")));
        String xmlStr = this.getXml("/template/makecode.xml", params);
        return xmlStr;
    }
    
    public String centerDecryptXml() throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("TransactionID", "99193714");
        params.put("SPID", "99");
        params.put("PubInfo", "<![CDATA[MDAxMDYwMDUxOTkwMTAwMDAzMDAwMDA0MDQwMTAwMDAwNDA0OTk0NTY3MzgyMzQ5MTU2MDk4NTM3OTM2]]>");
        params.put("Content", "<![CDATA[NDAzOTM5MzEzMzM0MzUzNjM5MzIzMDM5MzMzMDM3MzMyMzc0NzI2MTYzNjUzMjMwMzEzMjMwMzgzMjMzMzEzMzMxMzIzMjM5MzIzMDMwMzEzMjM4]]>");
        params.put("AssistNumber", "181839481337999749382701");
        String xmlStr = this.getXml("/template/centerDecrypt.xml", params);
        return xmlStr;
    }
    
    public String codeQueryXml(String businessId,String orgTID) throws IOException {
        String xmlStr = this.getXml("/template/codequery.xml");
        String transactionID = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS");
        Map<String, String> params = new HashMap<String, String>();
        params.put("TransactionID",transactionID );
        params.put("BusinessID",businessId );
        params.put("OrigTID", orgTID);
        xmlStr = this.replaceXml(xmlStr,params);
        return xmlStr;
    }
    
    /**
     * 生成web登陆报文
     * @return
     * @throws IOException
     */
    public String webAndClientLoginXml(String userName,String password,String checkType) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientLogin.xml");
        StringBuffer sbuffer = new StringBuffer();
        sbuffer.append(userName).append("WebAndClient");
        String userKey = MD5Util.encodeByMD5(sbuffer.toString());
        String desUserName = this.encode(userName.getBytes());
        String desPassword = this.encode(password.getBytes());
        
        Map<String, String> params = new HashMap<String, String>();
        params.put("UserName", desUserName);
        params.put("Password", desPassword);
        params.put("UserKey", userKey);
        params.put("CheckType", checkType);
        return this.replaceXml(xmlStr,params);
    }
    
    /**
     * webAndClient锁定报文
     * @return
     * @throws IOException
     */
    public String webAndClientLockXml(String checkType,String userId,String entryKey) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientLock.xml");
        Map<String, String> params = new HashMap<String, String>();
        String checkSum = MD5Util.encodeByMD5(entryKey + userId + checkType);
        params.put("CheckType",checkType);
        params.put("UserID",userId);
        params.put("UserKey",checkSum);
        return this.replaceXml(xmlStr, params);
    }
    
    /**
     * webAndClient锁定报文
     * @return
     * @throws IOException
     */
    public String webAndClientLockByNameXml(String checkType,String userName,String deviceId) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientLockByName.xml");
        userName = this.encrypt(userName);
        Map<String, String> params = new HashMap<String, String>();
        params.put("UserName",userName);
        params.put("CheckType",checkType);
        params.put("DeviceID",deviceId);
        return this.replaceXml(xmlStr, params);
    }
    
    /**
     * webAndClient心跳程序
     * @return
     * @throws IOException
     */
    public String webAndClientHeartbeatXml(String checkType,String userId,String entryKey) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientHeartbeat.xml");
        Map<String, String> params = new HashMap<String, String>();
        
        String checkSum = MD5Util.encodeByMD5(entryKey + userId + checkType);
        params.put("CheckType",checkType);
        params.put("UserID",userId);
        params.put("UserKey",checkSum);
        return this.replaceXml(xmlStr, params);
    }
    
    /**
     * webAndClient心跳程序
     * @return
     * @throws IOException
     */
    public String webAndClientLogout(String userId,String entryKey) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientLogout.xml");
        Map<String, String> params = new HashMap<String, String>();
        
        String checkSum = MD5Util.encodeByMD5(entryKey + userId);
        params.put("UserID",userId);
        params.put("CheckSum",checkSum.toLowerCase());
        return this.replaceXml(xmlStr, params);
    }
    
    
    public String encrypt(String str) throws IOException {
        final String CHARSET = "UTF-8";
        byte[] buf = DESUtil.encryptMode(DESUtil.keyBytes, str.getBytes(CHARSET));
        return Base64.encode(buf);
    }
    
    public String decrypt(String str) throws IOException {
        final String CHARSET = "UTF-8";
        byte[] buf = Base64.decode(str);
        return new String(DESUtil.decryptMode(DESUtil.keyBytes, buf),CHARSET);
    }
    
    /**
     * webAndClient心跳程序
     * @return
     * @throws IOException
     */
    public String webAndClientUpdatePwd(String checkType,String userId,String entryKey,
            String password,String newPassword) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientUpdatePwd.xml");
        Map<String, String> params = new HashMap<String, String>();

        String checkSum = MD5Util.encodeByMD5(entryKey + userId + checkType);
        params.put("UserID",userId);
        params.put("Password",encrypt(password));
        params.put("NewPassword",encrypt(newPassword));
        params.put("CheckType",checkType);
        params.put("DeviceID","11111");
        params.put("CheckSum",checkSum);
        return this.replaceXml(xmlStr, params);
    }
    
    
    /**
     * webAndClient心跳程序
     * @return
     * @throws IOException
     */
    public String webAndClientValidate(String checkType,String userId,String entryKey,
            String contentType,String content,
            String applyAmount,String applyPassword) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientValidate.xml");
        Map<String, String> params = new HashMap<String, String>();
        
        String checkSum = MD5Util.encodeByMD5(entryKey + userId + checkType);
        String transactionId = this.genTransactionId();
        params.put("TransactionID",transactionId);
        params.put("UserID",userId);
        params.put("CheckSum",checkSum);
        params.put("DeviceID","");
        params.put("OperateType","2");
        params.put("ContentType",contentType);
        params.put("Content",content);
        params.put("CheckType",checkType);
        params.put("ApplyAmount",applyAmount);
        params.put("ApplyPassword",applyPassword);
        return this.replaceXml(xmlStr, params);
    }
    
    /**
     * webAndClient心跳程序
     * @return
     * @throws IOException
     */
    public String webAndClientReversal(String checkType,String userId,String entryKey,String orgTID) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientReversal.xml");
        Map<String, String> params = new HashMap<String, String>();
        
        String checkSum = MD5Util.encodeByMD5(entryKey + userId + checkType);
        String transactionId = this.genTransactionId();
        params.put("TransactionID",transactionId);
        params.put("UserID",userId);
        params.put("CheckSum",checkSum);
        params.put("DeviceID","");
        params.put("OrgTID",orgTID);
        params.put("CheckType",checkType);
        return this.replaceXml(xmlStr, params);
    }
    
    /**
     * webAndClientUpdatePwdEmail修改密码邮箱
     * @return
     * @throws IOException
     */
    public String webAndClientUpdatePwdEmail(String checkType,String userId,String entryKey,String newEmail) throws IOException {
        String xmlStr = this.getXml("/template/webAndClientUpdatePwdEmail.xml");
        Map<String, String> params = new HashMap<String, String>();
        
        String checkSum = MD5Util.encodeByMD5(entryKey + userId + newEmail);
        String transactionId = this.genTransactionId();
        params.put("TransactionID",transactionId);
        params.put("UserID",userId);
        params.put("NewEmail",newEmail);
        params.put("CheckType",checkType);
        params.put("CheckSum",checkSum);
        params.put("DeviceID","");
        return this.replaceXml(xmlStr, params);
    }
    
    
    public String deviceSignXml(String deviceId) throws IOException {
        String xmlStr = this.getXml("/template/deviceSign.xml");
        Map<String, String> params = new HashMap<String, String>();
        params.put("DeviceID",deviceId);
        return this.replaceXml(xmlStr, params);
    }
    
    public String deviceValidateXml(String businessId,String deviceId,
            String contentType,String content,
            String applyAmount,String applyPassword) throws IOException {
        String xmlStr = this.getXml("/template/deviceValidate.xml");
        Map<String, String> params = new HashMap<String, String>();
        String transactionId = this.genTransactionId(businessId,null);
        params.put("TransactionID",transactionId);
        params.put("BusinessID",businessId);
        params.put("DeviceID",deviceId);
        params.put("Content",content);
        params.put("ContentType",contentType);
        params.put("ApplyAmount",applyAmount);
        params.put("ApplyPassword",applyPassword);
        return this.replaceXml(xmlStr, params);
    }
    
    public String deviceReversalXml(String businessId,String deviceId,String OrgTID) throws IOException {
        String xmlStr = this.getXml("/template/deviceReversal.xml");
        Map<String, String> params = new HashMap<String, String>();
        
        String transactionId = this.genTransactionId(businessId,null);
        params.put("TransactionID",transactionId);
        params.put("BusinessID",businessId);
        params.put("DeviceID",deviceId);
        params.put("OrgTID",OrgTID);
        params.put("SubmitTime",DateFormatUtils.format(new Date(), "yyyyMMddHHmmss"));
        return this.replaceXml(xmlStr, params);
    }
}
